package com.example.securitydemos.config;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.session.HttpSessionEventPublisher;

/**
 * @author linjy on 2023/1/31
 * 会话管理之会话并发控制2:阻止新用户登录
 */
//@EnableWebSecurity(debug = true)
public class SecurityConfig_会话管理之会话并发控制2 extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**")
                .hasRole("ADMIN")
                .antMatchers("/user/**")
                .hasRole("USER")
                .antMatchers("/app/**")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .csrf()
                .disable()
                .formLogin()
                .permitAll()
                .and()
                //进行会话管理
                .sessionManagement()
                //最大并发会话数,设置单个用户允许同时在线的最大会话数,如果没有额外配置,重新登录的会话会踢掉旧的会话.
                .maximumSessions(1)
                //当达到最大会话数时,阻止建立新会话,而不是踢掉旧的会话.默认为false
                .maxSessionsPreventsLogin(true);
    }

    /**
     * 监听session创建及销毁事件，来及时清理session的记录，以确保最新的session状态可以被及时感知到。
     */
    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {

        return new HttpSessionEventPublisher();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {

        return NoOpPasswordEncoder.getInstance();
    }

}
